#include <QApplication>
#include <QPushButton>
#include <QFont>
#include <QWidget>
#include <QSizePolicy>
#include <QLCDNumber>
#include <QSlider>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QObject>
#include <QString>
#include <QColor>
#include <QListWidget>
#include <QPainter>
#include <QCheckBox>
#include <QLabel>
#include <QPalette>

#include <QStringList>
#include <QTreeWidget>
#include <QTreeWidgetItem>

#include <QFileDialog>

#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_grid.h>
#include <qwt_legend.h>
#include <qwt_data.h>
#include <qwt_text.h>
#include <qwt_scale_engine.h>
#include <qwt_wheel.h>

#include <math.h>
#include <iostream>
#include <string>
#include <sstream>

#include "qplot.h"
#include "see.h"
#include "globalconstants.h"


qTrace::qTrace(QWidget *parent)
{
  setMaximumHeight(630);
  QGridLayout *layout = new QGridLayout;
  
  maxVem=1;
  for(int i=0;i<3;i++){
    tracePlot[i]=new QwtPlot();
    tracePlot[i]->setCanvasBackground(colorTraceBack);
    tracePlot[i]->setAxisTitle(0, "VEM");
    tracePlot[i]->setAxisTitle(2, "ns");
    tracePlot[i]->setAxisScale(0,0,1);
    tracePlot[i]->setAxisScale(2,0,1);
    
    QwtPlotGrid *grid = new QwtPlotGrid;
    grid->enableXMin(true);
    grid->enableYMin(true);
    grid->setMajPen(QPen(Qt::gray, 0, Qt::DotLine));
    grid->setMinPen(QPen(colorTraceBack, 0 , Qt::NoPen));
    grid->attach(tracePlot[i]);
    
    totalVEM[i]=new QwtPlotCurve();
    totalVEM[i]->setStyle(QwtPlotCurve::Steps);
    totalVEM[i]->setPen(QPen(colorVemLine,1));
    totalVEM[i]->setBrush(QBrush(colorVemFill));
    totalVEM[i]->attach(tracePlot[i]);
    
    layout->addWidget(tracePlot[i],i,0,1,3);
  }
  
  zoomV=new QSlider(Qt::Vertical);
  zoomV->setRange(1,100);
  zoomV->setValue(100);
  layout->addWidget(zoomV,0,4,3,1);
  
  
  QHBoxLayout *subLayout = new QHBoxLayout;
  
  ruedita=new QwtWheel;
  ruedita->setRange(0,1);
  ruedita->setValue(0);
  
  zoomH=new QSlider(Qt::Horizontal);
  zoomH->setRange(0,1);
  zoomH->setValue(1);
  
  layout->addWidget(zoomH,3,1,1,1);
  layout->addWidget(ruedita,3,2,1,1);
  layout->setColumnStretch(0, 10);
  layout->setColumnStretch(1, 50);

  setLayout(layout);
  
  QObject::connect(ruedita,SIGNAL(valueChanged(double)),this,SLOT(movePlot(double)));
  QObject::connect(zoomH,SIGNAL(valueChanged(int)),this,SLOT(rescaleHPlot(int)));
  QObject::connect(zoomV,SIGNAL(valueChanged(int)),this,SLOT(rescaleVPlot(int)));
}

qTrace::qTrace(pmtTrace* trace,QWidget *parent)//ya se lo puede sacar
{

  setMaximumHeight(630);
  QGridLayout *layout = new QGridLayout;
  
  QVBoxLayout *subLayoutTraces = new QVBoxLayout;
  //cout << "Antes de crear y llenar los plots\n";
  maxVem=0;
  for(int i=0;i<3;i++){
    tracePlot[i]=new QwtPlot();
    tracePlot[i]->setCanvasBackground(colorTraceBack);
    tracePlot[i]->setAxisTitle(0, "VEM");
    tracePlot[i]->setAxisTitle(2, "ns");
    QwtPlotGrid *grid = new QwtPlotGrid;
    grid->enableXMin(true);
    grid->enableYMin(true);
    grid->setMajPen(QPen(Qt::gray, 0, Qt::DotLine));
    grid->setMinPen(QPen(colorTraceBack, 0 , Qt::NoPen));
    grid->attach(tracePlot[i]);
    
    totalVEM[i]=new QwtPlotCurve();
    totalVEM[i]->setStyle(QwtPlotCurve::Steps);
    totalVEM[i]->setPen(QPen(colorVemLine,1));
    totalVEM[i]->setBrush(QBrush(colorVemFill));
    totalVEM[i]->setData(trace->getTrace(i+1).x,trace->getTrace(i+1).y, trace->getTrace(i+1).size);
    totalVEM[i]->attach(tracePlot[i]);
    double localHi=totalVEM[i]->maxYValue();
    if(maxVem<localHi) maxVem=localHi;
    subLayoutTraces->addWidget(tracePlot[i],i,0);
  }
  for(int i=0;i<3;i++){
    tracePlot[i]->setAxisScale(0,0,maxVem);
    tracePlot[i]->replot();
  }
  layout->addLayout(subLayoutTraces,0,0);
  
  xMin=tracePlot[0]->axisScaleDiv(2)->lBound();
  xMax=tracePlot[0]->axisScaleDiv(2)->hBound();
  
  limInf=xMin;
  limSup=xMax;
  
  range=xMax-xMin;
  
  zoomV=new QSlider(Qt::Vertical);
  zoomV->setRange(1,100);
  zoomV->setValue(100);
  layout->addWidget(zoomV,0,1);
  
  
  QHBoxLayout *subLayout = new QHBoxLayout;
  
  ruedita=new QwtWheel;
  ruedita->setRange(0,range);
  ruedita->setValue(0);
  
  zoomH=new QSlider(Qt::Horizontal);
  zoomH->setRange(5,range);
  zoomH->setValue(range);
  
  subLayout->addWidget(zoomH);
  subLayout->addWidget(ruedita);
  
  layout->addLayout(subLayout,1,0);

  setLayout(layout);
  
  QObject::connect(ruedita,SIGNAL(valueChanged(double)),this,SLOT(movePlot(double)));
  QObject::connect(zoomH,SIGNAL(valueChanged(int)),this,SLOT(rescaleHPlot(int)));
  QObject::connect(zoomV,SIGNAL(valueChanged(int)),this,SLOT(rescaleVPlot(int)));
  //cout << "despues de crear y llenar los plots\n";
}

qTrace::~qTrace()
{

}

void qTrace::setValue(pmtTrace* trace)
{

  
  maxVem=0;
  for(int i=0;i<3;i++){
    totalVEM[i]->setData(trace->getTrace(i+1).x, trace->getTrace(i+1).y, trace->getTrace(i+1).size);
    double localHi=totalVEM[i]->maxYValue();
    if(maxVem<localHi) maxVem=localHi;
    //tracePlot[i]->replot();
  }
  
  xMin=0;//tracePlot[0]->axisScaleDiv(2)->lBound();//mandarno a setValue
  xMax=6000;//tracePlot[0]->axisScaleDiv(2)->hBound();//mandarno a setValue
  
  limInf=xMin;//mandarno a setValue
  limSup=xMax;//mandarno a setValue
  
  range=xMax-xMin;//mandarno a setValue
  range=6000;
  ruedita->setRange(0,range);
  ruedita->setValue(0);
  zoomH->setRange(5,range);
  zoomH->setValue(range);
  zoomV->setValue(100);
  
  for(int i=0;i<3;i++){
    tracePlot[i]->setAxisScale(0,0,maxVem);
    tracePlot[i]->setAxisScale(2,0,range);
    tracePlot[i]->replot();
  }

}

void qTrace::rescaleHPlot(int interval)
{
  range=interval;
  limSup=limInf+range;
  for(int i=0;i<3;i++){
    tracePlot[i]->setAxisScale(2,limInf,limSup);
    tracePlot[i]->replot();
  }
}

void qTrace::rescaleVPlot(int scale)
{
  double zoomFrac=scale/100.;
  //cout <<"\nFactor vertical: "<<zoomFrac<<endl;
  //cout <<"MaxVem: "<<maxVem<<endl;
  for(int i=0;i<3;i++){
    tracePlot[i]->setAxisScale(0,0,maxVem*zoomFrac);
    tracePlot[i]->replot();
  }
}

void qTrace::movePlot(double shift)
{
  limInf=shift;
  limSup=shift+range;
  //cout << "\nse mueve!!\n";
  for(int i=0;i<3;i++){
    tracePlot[i]->setAxisScale(2,limInf,limSup);
    tracePlot[i]->replot();
  }
}
    

qTankList::qTankList(QWidget *parent)
{
  treeWidget = new QTreeWidget();
  treeWidget->setColumnCount(2);
  treeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
  QTreeWidgetItem *header=new QTreeWidgetItem();
  header->setText(0,"ID");
  header->setText(1,"tiempo (ns)");
  treeWidget->setHeaderItem(header);
  treeWidget->setIndentation(0);
  
  setMaximumWidth(250);
  setMinimumWidth(250);
  
  QGridLayout *layout = new QGridLayout;
  layout->addWidget(treeWidget,0,0);
  setLayout(layout);
  
  QObject::connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(itemSelectionChanged()));
  //setTankList(candList);
}


qTankList::qTankList(vector<tCandidate>* candList,QWidget *parent)//ya se la puede borrar
{

  treeWidget = new QTreeWidget();
  treeWidget->setColumnCount(2);
  treeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
  QTreeWidgetItem *header=new QTreeWidgetItem();
  header->setText(0,"ID");
  header->setText(1,"tiempo (ns)");
  treeWidget->setHeaderItem(header);
  treeWidget->setIndentation(0);
  
  setMaximumWidth(250);
  setMinimumWidth(250);
  
  QGridLayout *layout = new QGridLayout;
  layout->addWidget(treeWidget,0,0);
  setLayout(layout);
  
  QObject::connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(itemSelectionChanged()));
  setTankList(candList);
}

void qTankList::setTankList(vector<tCandidate>* candList)
{
  candList_pointer=candList;
  externalSelection=1;
  treeWidget->clear();
  treeItems.clear();
  indice.clear();
  sorted_sId.clear();
  sorted_ns.clear();
  for(int i=0;i<candList->size();i++){
    indice.push_back(i);
    sorted_sId.push_back(candList->at(i).sId);
    sorted_ns.push_back(candList->at(i).ns);
  }
  bool faltaOrdenar;
  
  do{
    faltaOrdenar=0;
    for(int i=0;i<sorted_ns.size()-1;i++){
      if(sorted_ns[i]>sorted_ns[i+1]){
        int aux=indice[i];
        indice[i]=indice[i+1];
        indice[i+1]=aux;
        aux=sorted_sId[i];
        sorted_sId[i]=sorted_sId[i+1];
        sorted_sId[i+1]=aux;
        aux=sorted_ns[i];
        sorted_ns[i]=sorted_ns[i+1];
        sorted_ns[i+1]=aux;
        faltaOrdenar=1;
      }
    }
  }while(faltaOrdenar);
  
  for(int i=0;i<candList->size();i++){
    QString qsAux1,qsAux2;
    qsAux1.setNum(candList->at(indice[i]).sId);
    qsAux2.setNum(candList->at(indice[i]).ns);
    
    QTreeWidgetItem *treeItem;
    treeItems.push_back(treeItem);
    treeItems[i] = new QTreeWidgetItem(treeWidget);
    treeItems[i]->setText(0,qsAux1);
    treeItems[i]->setText(1,qsAux2);
    
    switch (candList->at(indice[i]).lt) {
      case eToT:
        treeItems[i]->setBackgroundColor(0,colorToT);
        treeItems[i]->setIcon(0,QIcon(iconToT));
        treeItems[i]->setBackgroundColor(1,colorToT);
        break;
      case eThr2 :
        treeItems[i]->setBackgroundColor(0,colorThr2);
        treeItems[i]->setIcon(0,QIcon(iconThr2));
        treeItems[i]->setBackgroundColor(1,colorThr2);
        break;
      case eThr1 :
        treeItems[i]->setBackgroundColor(0,colorThr1);
        treeItems[i]->setIcon(0,QIcon(iconThr1));
        treeItems[i]->setBackgroundColor(1,colorThr1);
        break;
    }
  }
  
  externalSelection=1;
  treeWidget->clearSelection();
  externalSelection=1;
  treeWidget->setItemSelected(treeWidget->topLevelItem(0),1);
  externalSelection=1;
  treeWidget->scrollToItem(treeWidget->topLevelItem(0));
  externalSelection=0;
  emit externalTankSelect(candList->at(indice[0]).sId,candList->at(indice[0]).lt,indice[0]);
}

int qTankList::getTankIndex(int sId)
{
  int ind=-1;
  for(int i=0;i<sorted_sId.size();i++){
    if(sId==sorted_sId[i]){
      ind=i;
      break;
    }
  }
  if(ind<0){
    cout<<"\nError en qTankList::getTankIndex. Estacion inexistente\n";
    return -1;
  }
  return indice[ind];
}

void qTankList::tankSelect(int sId)
{
  //cout <<"\nen qTankList::tankSelect\n";
  int ind=-1;
  for(int i=0;i<sorted_sId.size();i++){
    if(sId==sorted_sId[i]){
      ind=i;
      break;
    }
  }
  if(ind<0){
    cout<<"\nError en qTankList::tankSelect. Estacion inexistente\n";
    return;
  }
  externalSelection=1;
  treeWidget->clearSelection();
  externalSelection=1;
  treeWidget->setItemSelected(treeWidget->topLevelItem(ind),1);
  externalSelection=1;
  treeWidget->scrollToItem(treeWidget->topLevelItem(ind));
  externalSelection=0;
}

void qTankList::itemSelectionChanged()
{
  if(externalSelection){
    externalSelection=0;
    return;
  }
  //cout <<"\nqTankList::itemSelectionChanged()\n";
  int sId=treeWidget->currentItem()->text(0).toInt();
  eLT lt=candList_pointer->at(indice[treeWidget->indexOfTopLevelItem(treeWidget->currentItem())]).lt;
  emit externalTankSelect(sId,lt,indice[treeWidget->indexOfTopLevelItem(treeWidget->currentItem())]);
}


qEventsList::qEventsList(QWidget *parent)
{
  treeWidget = new QTreeWidget();
  treeWidget->setColumnCount(3);
  treeWidget->setAlternatingRowColors(1);
  treeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
  QTreeWidgetItem *header = new QTreeWidgetItem();
  header->setText(0,"ID del evento");
  header->setText(1,"Candidatos");
  header->setText(2,"index");
  treeWidget->setHeaderItem(header);
  treeWidget->setColumnHidden(2,1);
  treeWidget->setIndentation(0);
  
  setMaximumWidth(250);
  setMinimumWidth(250);
  
  QGridLayout *layout = new QGridLayout;
  layout->addWidget(treeWidget,0,0);
  setLayout(layout);
  
  QObject::connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(itemSelectionChanged()));
  //setEventsList(eventsList);
}


qEventsList::qEventsList(vector<tEventsummary> *eventsList,QWidget *parent)
{
  treeWidget = new QTreeWidget();
  treeWidget->setColumnCount(3);
  treeWidget->setAlternatingRowColors(1);
  treeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
  QTreeWidgetItem *header = new QTreeWidgetItem();
  header->setText(0,"ID del evento");
  header->setText(1,"Candidatos");
  header->setText(2,"index");
  treeWidget->setHeaderItem(header);
  treeWidget->setColumnHidden(2,1);
  treeWidget->setIndentation(0);
  
  setMaximumWidth(250);
  setMinimumWidth(250);
  
  QGridLayout *layout = new QGridLayout;
  layout->addWidget(treeWidget,0,0);
  setLayout(layout);
  
  QObject::connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(itemSelectionChanged()));
  setEventsList(eventsList);
}

void qEventsList::setEventsList(vector<tEventsummary> *eventsList)
{
  eventsList_pointer=eventsList;
  externalSelection=1;
  treeWidget->clear();
  treeItems.clear();
  
  for(int i=0;i<eventsList->size();i++){
    QString qsAux1,qsAux2,qsAux3;
    qsAux1.setNum(eventsList->at(i).Id);
    qsAux2.setNum(eventsList->at(i).candN);
    qsAux3.setNum(eventsList->at(i).fileIndex);
    
    QTreeWidgetItem *treeItem;
    treeItems.push_back(treeItem);
    treeItems[i] = new QTreeWidgetItem(treeWidget);
    treeItems[i]->setText(0,qsAux1);
    treeItems[i]->setText(1,qsAux2);
    treeItems[i]->setText(2,qsAux3);
    treeItems[i]->setIcon(0,QIcon(iconEvent));
  }
  externalSelection=1;
  treeWidget->clearSelection();
  treeWidget->setItemSelected(treeWidget->topLevelItem(0),1);
  treeWidget->scrollToItem(treeWidget->topLevelItem(0));
  externalSelection=0;
}
    
void qEventsList::itemSelectionChanged()
{
  if(externalSelection){
    externalSelection=0;
    return;
  }
  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
  //cout <<"\nqEventsList::itemSelectionChanged()\n";
  int eventIndexNo=treeWidget->currentItem()->text(2).toInt();
  //cout <<"\nNumero de indice: "<<eventIndexNo<<endl;
  emit eventSelected(eventIndexNo);
}
